package Jesale.PathFinderWS;

import javax.jws.WebMethod;
import javax.jws.WebService;

import editor.modelo.Floor;
import editor.modelo.Portal;
import editor.modelo.Portal.Tipo;

import server.buscador.ANode;
import server.buscador.AStar;
import server.buscador.NodeEdge;
import server.buscador.SpaceNode;

@WebService(endpointInterface = "Jesale.PathFinderWS.PathFinderInterface")
public class PathFinder implements PathFinderInterface {


	private AStar buscador;

	public PathFinder(){
		buscador = new AStar();
		getPath("inicio", "Mezanine");

	}
	@WebMethod
	public String getPath(String source, String target) {
		// TODO retornar el camino
		System.out.println("source: "+source+", target: "+target);
		
		ANode meta = buscador.search(source, target);
		
		if(meta != null){
			System.out.println("Camino encontrado!");
			meta.camino.add(meta.nodo);

			StringBuilder sb = new StringBuilder();
			Floor pisoAnterior = null;

			sb.append("[");//inicio del json.
			SpaceNode nodoInicial = meta.camino.remove(0);
			appendSpaceHeader(sb, nodoInicial.getPisoPadre());
			appendNodeCoordinates(sb, nodoInicial, null); //imprime centroide del nodo
			sb.append(",");
			appendNodeCoordinates(sb, nodoInicial, meta.camino.size()>0 ? meta.camino.get(0): null);
			pisoAnterior = nodoInicial.getPisoPadre();
			int i = 1; 
			for (SpaceNode nodo : meta.camino) {
				
				if(nodo.getPisoPadre() != pisoAnterior){ 
					pisoAnterior = nodo.getPisoPadre();
					appendSpaceTail(sb);
					sb.append(",");
					
					//jesus
					if (i<meta.camino.size()){
						SpaceNode sig = meta.camino.get(i);
						NodeEdge p = findPortal(nodo, sig);
						if (p.getTipo() == Tipo.dstair || p.getTipo() == Tipo.ustair){
							sb.append("{tipo:'portal'},");
						}
					}
					
					appendSpaceHeader(sb, nodo.getPisoPadre());

				}else{
					sb.append(",");
				}
				appendNodeCoordinates(sb, nodo, i<meta.camino.size() ? meta.camino.get(i++): null);
			}

			appendSpaceTail(sb);
			sb.append("]");
			System.out.println(sb.toString());
			return sb.toString();
		}
		System.out.println("Camino NO encontrado!");
		return "{'error': 'Camino no encontrado';}";
	}

	private void appendSpaceTail(StringBuilder sb) {
		sb.append("]}");
	}
	
	private void appendNodeCoordinates(StringBuilder sb, SpaceNode nodo, SpaceNode sig) {
		if(sig != null){ //sig == null termine el camino
			NodeEdge p = findPortal(nodo, sig);
			sb.append("{'nombre':");
			sb.append("'"+ nodo.getId()+"',");
			sb.append("'tipo': 'space',");
			sb.append("'x':");
			sb.append((int)p.getPosition().getX());
			sb.append(",'y':");
			sb.append((int)p.getPosition().getY()); //source
			sb.append(",'z':");
			sb.append((int)nodo.getHeight());
			sb.append("}");
			
			if(sig.getPisoPadre() != nodo.getPisoPadre()) return; //
			
			if(p.getTipo() == Portal.Tipo.dstair || p.getTipo() == Portal.Tipo.ustair){
				sb.append(",{'nombre':'dummy',");
				sb.append("'tipo': 'escalera',");
				sb.append("'x':");
				sb.append((int)p.getPtoTarget().getX());
				sb.append(",'y':");
				sb.append((int)p.getPtoTarget().getY()); //target
				sb.append(",'z':");
				sb.append((int)sig.getHeight()); 
				sb.append("}");
			}
		}
		else {
			sb.append("{'nombre':");
			sb.append("'"+ nodo.getId()+"',");
			sb.append("'tipo': 'space',");
			sb.append("'x':");
			sb.append((int)nodo.getCentro().getX());
			sb.append(",'y':");
			sb.append((int)nodo.getCentro().getY());
			sb.append(",'z':");
			sb.append((int)nodo.getHeight());
			sb.append("}");
		}
	}
	
	private NodeEdge findPortal(SpaceNode nodo, SpaceNode sig) {
		for (NodeEdge p : nodo.getPortals()) {
			if(p.getTarget() == sig) return p;
		}
		return null;
	}
	private void appendSpaceHeader(StringBuilder sb, Floor floor) {
		sb.append("{tipo:'plano'," +
				"id:'"+ floor.getCompleteFloorName() +"'," +
				"level:'"+ floor.getLevel() +"'," +
				"puntos:[");
	}

}